package cqie.frame.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.api.ApiController;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import cqie.frame.entity.*;
import cqie.frame.entity.po.SelectListItem;
import cqie.frame.entity.qo.EmpEvaluateRecordQo;
import cqie.frame.entity.qo.StudentEvaluateRecordQo;
import cqie.frame.entity.vo.*;
import cqie.frame.response.CodeMsg;
import cqie.frame.response.ResultJson;
import cqie.frame.service.*;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import org.thymeleaf.util.StringUtils;

import javax.annotation.Resource;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 评教记录(EvaluateRecord)表控制层
 *
 * @author makejava
 * @since 2021-10-11 08:41:41
 */
@RestController
@RequestMapping("/evaluateRecord")
public class EvaluateRecordController extends ApiController {
    /**
     * 服务对象
     */
    @Resource
    private IEvaluateRecordService iEvaluateRecordService;
    @Resource
    private IClazzService iClazzService;
    @Resource
    private IClazzCourseTeacherService iClazzCourseTeacherService;
    @Resource
    private ICourseService iCourseService;
    @Resource
    private IEmpService iEmpService;
    @Resource
    private IEvaluateTypeService iEvaluateTypeService;
    @Resource
    private IEvaluateTaskService iEvaluateTaskService;
    @Resource
    private IEvaluateTargetService iEvaluateTargetService;
    @Resource
    private IEvaluateTargetOptionService iEvaluateTargetOptionService;
    @Resource
    private IUserRoleService iUserRoleService;
    @Resource
    private IDeptService iDeptService;

    @ApiOperation(value = "查看评教分数")
    @PostMapping(value = "/showScore")
    public ResultJson showScore(@RequestBody EmpEvaluateRecordQo qo) {
        try {
            //1.根据教师ID，任务ID，找出所有评教记录
            QueryWrapper<EvaluateRecord> qw = new QueryWrapper<>();
            if (qo.getEvaluateTaskId() != null) {
                qw.eq("evaluateTaskId", qo.getEvaluateTaskId());
            }
            if (qo.getTeacherId() != null) {
                qw.eq("teacherId", qo.getTeacherId());
            }
            Emp emp = iEmpService.getById(qo.getTeacherId());
            //2.执行查询

            List<EvaluateRecord> datas = iEvaluateRecordService.list(qw);
            Score score = new Score();
            score.setTeacherName(emp.getName());
            Dept dept = iDeptService.getById(emp.getDeptId());
            score.setTeacherRole(dept.getName());
            if (datas.size()>0) {
                for (int i = 0; i < datas.size(); i++) {
                    long j = datas.get(i).getEvaluateTypeId();
                    //如果为学生评教
                    if (j == 1) {
                        //根据指标id和指标项id算分
                        EvaluateTarget evaluateTarget = iEvaluateTargetService.getById(datas.get(i).getEvaluateTargetId());
                        EvaluateTargetOption evaluateTargetOption = iEvaluateTargetOptionService.getById(datas.get(i).getEvaluateTargetOptionId());
                        score.setStudentScore(score.getStudentScore().add(evaluateTarget.getWeight().multiply(evaluateTargetOption.getScore())));
                    }
                    //如果为教师自评
                    if (j == 2) {
                        //根据指标id和指标项id算分
                        EvaluateTarget evaluateTarget = iEvaluateTargetService.getById(datas.get(i).getEvaluateTargetId());
                        EvaluateTargetOption evaluateTargetOption = iEvaluateTargetOptionService.getById(datas.get(i).getEvaluateTargetOptionId());
                        score.setTeacherScore(score.getTeacherScore().add(evaluateTarget.getWeight().multiply(evaluateTargetOption.getScore())));
                    }
                    if (j == 3) {
                        //根据指标id和指标项id算分
                        EvaluateTarget evaluateTarget = iEvaluateTargetService.getById(datas.get(i).getEvaluateTargetId());
                        EvaluateTargetOption evaluateTargetOption = iEvaluateTargetOptionService.getById(datas.get(i).getEvaluateTargetOptionId());
                        score.setPeerScore(score.getPeerScore().add(evaluateTarget.getWeight().multiply(evaluateTargetOption.getScore())));
                    }
                    if (j == 4) {
                        //根据指标id和指标项id算分
                        EvaluateTarget evaluateTarget = iEvaluateTargetService.getById(datas.get(i).getEvaluateTargetId());
                        EvaluateTargetOption evaluateTargetOption = iEvaluateTargetOptionService.getById(datas.get(i).getEvaluateTargetOptionId());
                        if (evaluateTarget.getParentId() != null) {
                            //如果有父级指标，迭代算分
                            score.setJiaoYScore(score.getJiaoYScore().add(scoreSelf(evaluateTarget, evaluateTargetOption.getScore())));
                        } else {
                            score.setJiaoYScore(score.getJiaoYScore().add(evaluateTarget.getWeight().multiply(evaluateTargetOption.getScore())));
                        }
                    }
                    if (j == 5) {
                        //根据指标id和指标项id算分
                        EvaluateTarget evaluateTarget = iEvaluateTargetService.getById(datas.get(i).getEvaluateTargetId());
                        EvaluateTargetOption evaluateTargetOption = iEvaluateTargetOptionService.getById(datas.get(i).getEvaluateTargetOptionId());
                        if (evaluateTarget.getParentId() != null) {
                            //如果有父级指标，迭代算分
                            score.setHeadScore(score.getHeadScore().add(scoreSelf(evaluateTarget, evaluateTargetOption.getScore())));
                        }
                    }
                }
                BigDecimal precent = new BigDecimal(0);
                BigDecimal a = new BigDecimal(0);
                BigDecimal b = new BigDecimal(0);
                BigDecimal c = new BigDecimal(0);
                BigDecimal d = new BigDecimal(0);
                BigDecimal e = new BigDecimal(0);
                if (score.getStudentScore().compareTo(new BigDecimal(0)) == 1) {

                    //1.根据教师ID，任务ID，找出所有评教记录
                    QueryWrapper<EvaluateRecord> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("evaluateTaskId", qo.getEvaluateTaskId());
                    queryWrapper.eq("teacherId", qo.getTeacherId());
                    queryWrapper.eq("evaluateTypeId", 1);
                    queryWrapper.groupBy("sysUserId");
                    //2.执行查询
                    List<EvaluateRecord> data = iEvaluateRecordService.list(queryWrapper);
                    a = a.add(new BigDecimal(data.size()));
                    EvaluateType evaluateType = iEvaluateTypeService.getById(1);
                    precent = precent.add(new BigDecimal(evaluateType.getWeight()));
                    score.setStudentScore(score.getStudentScore().multiply(new BigDecimal(evaluateType.getWeight())));
                }
                if (score.getTeacherScore().compareTo(new BigDecimal(0)) == 1) {
                    //1.根据教师ID，任务ID，找出所有评教记录
                    QueryWrapper<EvaluateRecord> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("evaluateTaskId", qo.getEvaluateTaskId());
                    queryWrapper.eq("teacherId", qo.getTeacherId());
                    queryWrapper.eq("evaluateTypeId", 2);
                    queryWrapper.groupBy("sysUserId");
                    //2.执行查询
                    List<EvaluateRecord> data = iEvaluateRecordService.list(queryWrapper);
                    b = b.add(new BigDecimal(data.size()));
                    EvaluateType evaluateType = iEvaluateTypeService.getById(2);
                    precent = precent.add(new BigDecimal(evaluateType.getWeight()));
                    score.setTeacherScore(score.getTeacherScore().multiply(new BigDecimal(evaluateType.getWeight())));
                }
                if (score.getPeerScore().compareTo(new BigDecimal(0)) == 1) {
                    //1.根据教师ID，任务ID，找出所有评教记录
                    QueryWrapper<EvaluateRecord> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("evaluateTaskId", qo.getEvaluateTaskId());
                    queryWrapper.eq("teacherId", qo.getTeacherId());
                    queryWrapper.eq("evaluateTypeId", 3);
                    queryWrapper.groupBy("sysUserId");
                    //2.执行查询
                    List<EvaluateRecord> data = iEvaluateRecordService.list(queryWrapper);
                    c = c.add(new BigDecimal(data.size()));
                    EvaluateType evaluateType = iEvaluateTypeService.getById(3);
                    precent = precent.add(new BigDecimal(evaluateType.getWeight()));
                    score.setPeerScore(score.getPeerScore().multiply(new BigDecimal(evaluateType.getWeight())));
                }
                if (score.getJiaoYScore().compareTo(new BigDecimal(0)) == 1) {
                    //1.根据教师ID，任务ID，找出所有评教记录
                    QueryWrapper<EvaluateRecord> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("evaluateTaskId", qo.getEvaluateTaskId());
                    queryWrapper.eq("teacherId", qo.getTeacherId());
                    queryWrapper.eq("evaluateTypeId", 4);
                    queryWrapper.groupBy("sysUserId");
                    //2.执行查询
                    List<EvaluateRecord> data = iEvaluateRecordService.list(queryWrapper);
                    d = d.add(new BigDecimal(data.size()));
                    EvaluateType evaluateType = iEvaluateTypeService.getById(4);
                    precent = precent.add(new BigDecimal(evaluateType.getWeight()));
                    score.setJiaoYScore(score.getJiaoYScore().multiply(new BigDecimal(evaluateType.getWeight())));
                }
                if (score.getHeadScore().compareTo(new BigDecimal(0)) == 1) {
                    //1.根据教师ID，任务ID，找出所有评教记录
                    QueryWrapper<EvaluateRecord> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("evaluateTaskId", qo.getEvaluateTaskId());
                    queryWrapper.eq("teacherId", qo.getTeacherId());
                    queryWrapper.eq("evaluateTypeId", 5);
                    queryWrapper.groupBy("sysUserId");
                    //2.执行查询
                    List<EvaluateRecord> data = iEvaluateRecordService.list(queryWrapper);
                    e = e.add(new BigDecimal(data.size()));
                    EvaluateType evaluateType = iEvaluateTypeService.getById(5);
                    precent = precent.add(new BigDecimal(evaluateType.getWeight()));
                    score.setHeadScore(score.getHeadScore().multiply(new BigDecimal(evaluateType.getWeight())));

                }
                BigDecimal newPrecent = BigDecimal.ONE.divide(precent, 2, BigDecimal.ROUND_HALF_DOWN);
                if (a.compareTo(BigDecimal.ZERO) == 1) {
                    score.setStudentScore(score.getStudentScore().multiply(newPrecent).divide(a, 2, BigDecimal.ROUND_HALF_DOWN));
                } else {
                    score.setStudentScore(score.getStudentScore().multiply(newPrecent));
                }
                if (b.compareTo(BigDecimal.ZERO) == 1) {
                    score.setTeacherScore(score.getTeacherScore().multiply(newPrecent).divide(b, 2, BigDecimal.ROUND_HALF_DOWN));

                } else {
                    score.setTeacherScore(score.getTeacherScore().multiply(newPrecent));
                }
                if (c.compareTo(BigDecimal.ZERO) == 1) {
                    score.setPeerScore(score.getPeerScore().multiply(newPrecent).divide(c, 2, BigDecimal.ROUND_HALF_DOWN));

                } else {
                    score.setPeerScore(score.getPeerScore().multiply(newPrecent));
                }
                if (d.compareTo(BigDecimal.ZERO) == 1) {
                    score.setJiaoYScore(score.getJiaoYScore().multiply(newPrecent).divide(d, 2, BigDecimal.ROUND_HALF_DOWN));

                } else {
                    score.setJiaoYScore(score.getJiaoYScore().multiply(newPrecent));
                }
                if (e.compareTo(BigDecimal.ZERO) == 1) {
                    score.setHeadScore(score.getHeadScore().multiply(newPrecent).divide(e, 2, BigDecimal.ROUND_HALF_DOWN));

                } else {
                    score.setHeadScore(score.getHeadScore().multiply(newPrecent));
                }
                score.setTotalScore(score.getStudentScore().add(score.getTeacherScore()).add(score.getPeerScore()).add(score.getJiaoYScore()).add(score.getHeadScore()));

                return ResultJson.success(score);
            }else {
                return ResultJson.success(score);
            }
        }catch (Exception e){
            System.out.println(e);
            return ResultJson.error(CodeMsg.SERVER_ERROR);
        }
    }

    private BigDecimal scoreSelf(EvaluateTarget evaluateTarget,BigDecimal score){
        if (evaluateTarget.getParentId()!=null){
            EvaluateTarget evaluateTarget1 = iEvaluateTargetService.getById(evaluateTarget.getParentId());
            BigDecimal score1 = evaluateTarget.getWeight().multiply(score);
            return scoreSelf(evaluateTarget1,score1);
        }else {
            return evaluateTarget.getWeight().multiply(score);
        }
    }

    @ApiOperation(value = "学生评教", response = StudentEvaluateRecordVo.class)
    @PostMapping(value = "/listPagedStudentEvaluate")
    public ResultJson listPagedStudentEvaluate(@RequestBody StudentEvaluateRecordQo qo) {
        try {
            Page<ClazzCourseTeacher> page = new Page<>(qo.getPageIndex(), qo.getPageSize());
            //1.查询条件
            QueryWrapper<ClazzCourseTeacher> qw = new QueryWrapper<>();
            //只有学生能够学生评教
            qw.inSql("clazzId", "select clazzId from student where userId=" + qo.getSysUserId());
            //2.执行查询
            IPage<ClazzCourseTeacher> datas = iClazzCourseTeacherService.page(page, qw);
            //3.生成返回值
            //映射准备-班级
            List<Clazz> allClazz = new ArrayList<>();
            List<Long> clazzIdRange = datas.getRecords().stream()
                    .filter(x -> x.getClazzId() != null)
                    .map(x -> x.getClazzId())
                    .distinct()
                    .collect(Collectors.toList());
            if (clazzIdRange.size() > 0) {
                QueryWrapper<Clazz> qwClazz = new QueryWrapper<>();
                qwClazz.in("id", clazzIdRange);
                allClazz = iClazzService.list(qwClazz);
            }
            //映射准备-课程
            List<Course> allCourse = new ArrayList<>();
            List<Long> courseIdRange = datas.getRecords().stream()
                    .filter(x -> x.getCourseId() != null)
                    .map(x -> x.getCourseId())
                    .distinct()
                    .collect(Collectors.toList());
            if (courseIdRange.size() > 0) {
                QueryWrapper<Course> qwCourse = new QueryWrapper<>();
                qwCourse.in("id", courseIdRange);
                allCourse = iCourseService.list(qwCourse);
            }
            //映射准备-教师
            List<Emp> allTeacher = new ArrayList<>();
            List<Long> teacherIdRange = datas.getRecords().stream()
                    .filter(x -> x.getTeacherId() != null)
                    .map(x -> x.getTeacherId())
                    .distinct()
                    .collect(Collectors.toList());
            if (teacherIdRange.size() > 0) {
                QueryWrapper<Emp> qwTeacher = new QueryWrapper<>();
                qwTeacher.in("id", teacherIdRange);
                allTeacher = iEmpService.list(qwTeacher);
            }

            //映射准备-评价记录
            List<EvaluateRecord> allEvaluateRecord = new ArrayList<>();
            if (qo.getEvaluateTaskId() != null && teacherIdRange.size() > 0) {
                QueryWrapper<EvaluateRecord> qwEvaluateRecord = new QueryWrapper<>();
                qwEvaluateRecord.in("teacherId", teacherIdRange);
                qwEvaluateRecord.eq("evaluateTaskId", qo.getEvaluateTaskId());
                qwEvaluateRecord.eq("evaluateTypeId", 1L);//学生评价
                qwEvaluateRecord.eq("sysUserId", qo.getSysUserId());
                allEvaluateRecord = iEvaluateRecordService.list(qwEvaluateRecord);
            }
            //映射准备-评价任务是否能评价
            Boolean canEvaluate = false;
            if (qo.getEvaluateTaskId() != null) {
                EvaluateTask evaluateTask = iEvaluateTaskService.getById(qo.getEvaluateTaskId());
                Date now = new Date();
                if (evaluateTask != null) {
                    //评教任务的时间在范围内且状态为正常
                    canEvaluate = now.compareTo(evaluateTask.getStartDate()) >= 0 && now.compareTo(evaluateTask.getEndDate()) < 0 && evaluateTask.getStatus().equals(0);
                }
            }
            //映射
            List<StudentEvaluateRecordVo> list = new ArrayList<>();
            IPage<StudentEvaluateRecordVo> ret = new Page<>();
            BeanUtils.copyProperties(datas, ret);
            for (ClazzCourseTeacher mo : datas.getRecords()) {
                StudentEvaluateRecordVo vo = new StudentEvaluateRecordVo();
                BeanUtils.copyProperties(mo, vo);
                //映射--班级
                vo.setClazzName(mapClazzNameById(mo.getClazzId(), allClazz));
                //映射--课程
                vo.setCourseName(mapCourseNameById(mo.getCourseId(), allCourse));
                //映射--教师
                vo.setTeacherName(mapTeacherNameById(mo.getTeacherId(), allTeacher));
                //映射--操作+选中备选项
                List<EvaluateRecord> findEvaluateRecordList = allEvaluateRecord.stream()
                        .filter(x -> x.getClazzId().equals(mo.getClazzId())
                                && x.getCourseId().equals(mo.getCourseId())
                                && x.getTeacherId().equals(mo.getTeacherId()))
                        .collect(Collectors.toList());
                if (findEvaluateRecordList.size() > 0) {
                    //op为2已经评教过该任务
                    vo.setOp(2);
                } else {
                    //op为1表示还未评教，0表示没选任务不能评价
                    vo.setOp(canEvaluate ? 1 : 0);
                }
                vo.setOptionIdList(findEvaluateRecordList.stream().map(EvaluateRecord::getEvaluateTargetOptionId).collect(Collectors.toList()));
                list.add(vo);
            }
            ret.setRecords(list);
            return ResultJson.success(ret);
        } catch (Exception ex) {
            return ResultJson.error(CodeMsg.SERVER_ERROR);
        }
    }

    @ApiOperation(value = "获取评价任务备选项", response = SelectListItem.class)
    @GetMapping(value = "/listAllEvaluateTask")
    public ResultJson listAllEvaluateTask() {
        try {
            List<SelectListItem> ret = new ArrayList<>();
            List<EvaluateTask> list = iEvaluateTaskService.list(null);
            for (EvaluateTask item : list) {
                ret.add(SelectListItem.SelectListItem(item.getId(), item.getName()));
            }
            return ResultJson.success(ret);
        } catch (Exception ex) {
            return ResultJson.error(CodeMsg.SERVER_ERROR);
        }
    }

    /**
     * 根据Id映射名称--班级
     */
    private String mapClazzNameById(Long id, List<Clazz> all) {
        if (id == null) {
            return null;
        }
        Clazz find = all.stream().filter(x -> x.getId().equals(id)).findFirst().orElse(null);
        if (find == null) {
            return null;
        }
        return find.getName();
    }

    /**
     * 根据Id映射名称--课程
     */
    private String mapCourseNameById(Long id, List<Course> all) {
        if (id == null) {
            return null;
        }
        Course find = all.stream().filter(x -> x.getId().equals(id)).findFirst().orElse(null);
        if (find == null) {
            return null;
        }
        return find.getName();
    }

    /**
     * 根据Id映射名称--教师
     */
    private String mapTeacherNameById(Long id, List<Emp> all) {
        if (id == null) {
            return null;
        }
        Emp find = all.stream().filter(x -> x.getId().equals(id)).findFirst().orElse(null);
        if (find == null) {
            return null;
        }
        return find.getName();
    }

    @ApiOperation(value = "评价指标树", notes = "构造elementUi需要的树表数据", response = EvaluateTargetTreeData.class)
    @GetMapping(value = "/listEvaluateTargetVoListByEvaluateTypeId")
    public ResultJson listEvaluateTargetVoListByEvaluateTypeId(Long evaluateTypeId) {
        try {
            List<EvaluateTargetVo> ret = new ArrayList<>();
            //评价指标--指定评教类型
            QueryWrapper<EvaluateTarget> qwEvaluateTarget = new QueryWrapper<>();
            qwEvaluateTarget.eq("evaluateTypeId", evaluateTypeId);
            List<EvaluateTarget> allEvaluateTarget = iEvaluateTargetService.list(qwEvaluateTarget);
            //评价指标的备选项--指定评教类型
            QueryWrapper<EvaluateTargetOption> qwEvaluateTargetOption = new QueryWrapper<>();
            qwEvaluateTargetOption.inSql("evaluateTargetId", "select id from Evaluate_Target where evaluateTypeId=" + evaluateTypeId);
            List<EvaluateTargetOption> allEvaluateTargetOption = iEvaluateTargetOptionService.list(qwEvaluateTargetOption);
            //评价类型
            EvaluateType evaluateType = iEvaluateTypeService.getById(evaluateTypeId);
            //一级指标
            List<EvaluateTarget> first = allEvaluateTarget.stream().filter(x -> x.getParentId() == null).sorted(Comparator.comparing(EvaluateTarget::getSortCode)).collect(Collectors.toList());
            first.forEach(mo -> {
                int index = first.indexOf(mo) + 1;
                addSelfAndChildren(index + ".", mo, ret, allEvaluateTarget, allEvaluateTargetOption, evaluateType);
            });
            return ResultJson.success(ret);
        } catch (Exception ex) {
            return ResultJson.error(CodeMsg.SERVER_ERROR);
        }
    }


    /**
     * 递归方法--EvaluateTarget-->EvaluateTargetTreeData
     * 要映射评价类型+从表备选项列表
     * 构造评价指标树用
     */
    private void addSelfAndChildren(String pref, EvaluateTarget mo, List<EvaluateTargetVo> ret, List<EvaluateTarget> allEvaluateTarget, List<EvaluateTargetOption> allEvaluateTargetOption, EvaluateType evaluateType) {
        //自己
        EvaluateTargetVo vo = new EvaluateTargetVo();
        BeanUtils.copyProperties(mo, vo);
        vo.setName(pref + vo.getName());
        //映射--评价类型名称
        vo.setEvaluateTypeName(evaluateType.getName());
        //映射--备选项列表
        List<EvaluateTargetOption> details = allEvaluateTargetOption.stream().filter(x -> x.getEvaluateTargetId().equals(mo.getId())).collect(Collectors.toList());
        vo.setEvaluateTargetOptionList(details);
        ret.add(vo);
        //子女
        List<EvaluateTarget> children = allEvaluateTarget.stream()
                .filter(x -> x.getParentId() != null && x.getParentId().equals(mo.getId()))
                .sorted(Comparator.comparing(EvaluateTarget::getSortCode))
                .collect(Collectors.toList());
        for (EvaluateTarget child : children) {
            int index = children.indexOf(child) + 1;
            addSelfAndChildren(pref + index + ".", child, ret, allEvaluateTarget, allEvaluateTargetOption, evaluateType);
        }
    }

    @ApiOperation(value = "保存评价记录", notes = "批量提交", response = EvaluateRecord.class)
    @PostMapping(value = "/saveRecord")
    public ResultJson saveRecord(@RequestBody List<EvaluateRecord> pos) {
        try {
            if (pos == null || pos.size() == 0) {
                return ResultJson.error(new CodeMsg(100, "没有数据需要保存"));
            }
            Date now = new Date();
            pos.forEach(po -> {
                po.setEvaluateTime(now);
            });
            iEvaluateRecordService.saveBatch(pos);
            return ResultJson.success(pos);
        } catch (Exception ex) {
            return ResultJson.error(CodeMsg.SERVER_ERROR);
        }
    }

    /**
     * 确定登录员工
     */
    private Emp getLoginEmp(Long sysUserId) {
        QueryWrapper<Emp> qw = new QueryWrapper<>();
        qw.eq("userId", sysUserId);
        return iEmpService.list(qw).stream().findFirst().orElse(null);
    }

    /**
     * 确定登录用户担任角色
     */
    private List<Long> getLoginRoleIdList(Long sysUserId) {
        QueryWrapper<UserRole> qw = new QueryWrapper<>();
        qw.eq("userId", sysUserId);
        List<UserRole> allUserRole = iUserRoleService.list(qw);
        return allUserRole.stream()
                .map(UserRole::getRoleId)
                .collect(Collectors.toList());
    }

    /**
     * 获取员工评价的部门范围
     */
    private List<Long> getEmpEvaluateDeptRange(Emp loginEmp, List<Long> roleIdList, List<Dept> allDept) {
        List<Long> ret = new ArrayList<>();
        if (loginEmp != null && loginEmp.getDeptId() != null) {
            if (roleIdList.contains(2L)) {//系主任--所在部门及其子部门
                generateDeptIdRange(loginEmp.getDeptId(), ret, allDept);//递归
            } else { //教研室主任 或 教师--所在部门
                ret.add(loginEmp.getDeptId());
            }
        }
        return ret;
    }

    /**
     * 递归方法:添加当前部门Id及子部门的Id到deptIdRange
     */
    private void generateDeptIdRange(Long selfId, List<Long> deptIdRange, List<Dept> all) {
        //自己
        deptIdRange.add(selfId);
        //子女
        List<Dept> children = all.stream().filter(x -> x.getParentId() != null && x.getParentId().equals(selfId)).collect(Collectors.toList());
        for (Dept dept : children) {
            generateDeptIdRange(dept.getId(), deptIdRange, all);
        }
    }

    @ApiOperation(value = "员工评教", response = EmpEvaluateRecordVo.class)
    @PostMapping(value = "/listPagedEmpEvaluate")
    public ResultJson listPagedEmpEvaluate(@RequestBody EmpEvaluateRecordQo qo) {
        try {
            Page<Emp> page = new Page<>(qo.getPageIndex(), qo.getPageSize());
            List<Dept> allDept = iDeptService.list(null);
            Emp loginEmp = getLoginEmp(qo.getSysUserId());
            List<Long> roleIdList = getLoginRoleIdList(qo.getSysUserId());
            //1.查询条件
            QueryWrapper<Emp> qw = new QueryWrapper<>();
            //确定登录员工的评价范围
            List<Long> evaluateRange = getEmpEvaluateDeptRange(loginEmp, roleIdList, allDept);
            if (evaluateRange.size() > 0) {
                qw.in("deptId", evaluateRange);
            } else {
                qw.eq("deptId", 0L);//登录员工的部门未知
            }
            //2.执行查询
            IPage<Emp> datas = iEmpService.page(page, qw);
            //3.生成返回值
            //映射准备-评价记录
            List<Long> teacherIdRange = datas.getRecords().stream().map(Emp::getId).collect(Collectors.toList());
            List<EvaluateRecord> allEvaluateRecord = new ArrayList<>();
            if (qo.getEvaluateTaskId() != null && teacherIdRange.size() > 0) {
                QueryWrapper<EvaluateRecord> qwEvaluateRecord = new QueryWrapper<>();
                qwEvaluateRecord.in("teacherId", teacherIdRange);
                qwEvaluateRecord.eq("evaluateTaskId", qo.getEvaluateTaskId());
                qwEvaluateRecord.in("evaluateTypeId", new Long[]{2L, 3L, 4L, 5L});
                qwEvaluateRecord.eq("sysUserId", qo.getSysUserId());
                allEvaluateRecord = iEvaluateRecordService.list(qwEvaluateRecord);
            }
            //映射准备-评价任务是否能评价
            Boolean canEvaluate = false;
            if (qo.getEvaluateTaskId() != null) {
                EvaluateTask evaluateTask = iEvaluateTaskService.getById(qo.getEvaluateTaskId());
                Date now = new Date();
                if (evaluateTask != null) {
                    canEvaluate = now.compareTo(evaluateTask.getStartDate()) >= 0 && now.compareTo(evaluateTask.getEndDate()) < 0 && evaluateTask.getStatus().equals(0);
                }
            }
            //映射
            IPage<EmpEvaluateRecordVo> ret = new Page<>();
            BeanUtils.copyProperties(datas, ret);
            List<EmpEvaluateRecordVo> list = new ArrayList<>();
            for (Emp mo : datas.getRecords()) {
                EmpEvaluateRecordVo vo = new EmpEvaluateRecordVo();
                BeanUtils.copyProperties(mo, vo);
                //映射--性别
                if (mo.getSex() != null) {
                    vo.setSexName(mo.getSex().equals(0) ? "男" : "女");
                }
                //映射--部门
                if (mo.getDeptId() != null) {
                    Dept dept = allDept.stream().filter(x -> x.getId().equals(mo.getDeptId())).findFirst().orElse(null);
                    if (dept != null) {
                        vo.setDeptName(dept.getName());
                    }
                }
                //映射--操作+选中备选项
                List<EvaluateRecord> find;
                //自评
                if (mo.getId().equals(loginEmp.getId()) && roleIdList.contains(4L)) {
                    find = allEvaluateRecord.stream().filter(x -> x.getEvaluateTypeId().equals(2L) && x.getTeacherId().equals(mo.getId())).collect(Collectors.toList());
                    vo.setOp2((find.size() > 0) ? 2 : (canEvaluate ? 1 : 0));
                    vo.setOptionIdList2(find.stream().map(EvaluateRecord::getEvaluateTargetOptionId).collect(Collectors.toList()));
                }
                //同行评教
                if (mo.getId().equals(loginEmp.getId()) == false && roleIdList.contains(4L)) {
                    find = allEvaluateRecord.stream().filter(x -> x.getEvaluateTypeId().equals(3L) && x.getTeacherId().equals(mo.getId())).collect(Collectors.toList());
                    vo.setOp3((find.size() > 0) ? 2 : (canEvaluate ? 1 : 0));
                    vo.setOptionIdList3(find.stream().map(EvaluateRecord::getEvaluateTargetOptionId).collect(Collectors.toList()));
                }
                //教研室评教
                if (mo.getId().equals(loginEmp.getId()) == false && roleIdList.contains(3L)) {
                    find = allEvaluateRecord.stream().filter(x -> x.getEvaluateTypeId().equals(4L) && x.getTeacherId().equals(mo.getId())).collect(Collectors.toList());
                    vo.setOp4((find.size() > 0) ? 2 : (canEvaluate ? 1 : 0));
                    vo.setOptionIdList4(find.stream().map(EvaluateRecord::getEvaluateTargetOptionId).collect(Collectors.toList()));
                }
                //系部评教
                if (mo.getId().equals(loginEmp.getId()) == false && roleIdList.contains(2L)) {
                    find = allEvaluateRecord.stream().filter(x -> x.getEvaluateTypeId().equals(5L) && x.getTeacherId().equals(mo.getId())).collect(Collectors.toList());
                    vo.setOp5((find.size() > 0) ? 2 : (canEvaluate ? 1 : 0));
                    vo.setOptionIdList5(find.stream().map(EvaluateRecord::getEvaluateTargetOptionId).collect(Collectors.toList()));
                }
                list.add(vo);
            }
            ret.setRecords(list);
            return ResultJson.success(ret);
        } catch (Exception ex) {
            return ResultJson.error(CodeMsg.SERVER_ERROR);
        }
    }
}
